package com.freesun.shop.controller;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.freesun.shop.anno.Log;
import com.freesun.shop.param.LoginParam;
import com.freesun.shop.service.SysUserService;
import com.freesun.shop.entity.SysUser;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
public class LoginController {
  private static Logger log = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    //UUID的前缀
    private static final String AUTH_CODE_PREFIX="AUTH:CODE:";
    @ApiOperation("用户的登录")
    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody LoginParam loginParam){
        String token=null;
        try {
        //登录之前先校验验证码
            checkAuthCode(loginParam.getSessionUUID(),loginParam.getImageCode());
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginParam.getPrincipal(),loginParam.getCredentials());
            Subject subject = SecurityUtils.getSubject();
            subject.login(usernamePasswordToken);
            token= subject.getSession().getId().toString();
        } catch (AccountException e) {

            return ResponseEntity.badRequest().body("用户名不存在或者过期");
        } catch (CredentialsException e){
            return ResponseEntity.badRequest().body("用户名密码错误");
        } catch (AuthenticationException e){
            return ResponseEntity.badRequest().body(e.getMessage());
        }
        return ResponseEntity.ok(token);
    }

    private void checkAuthCode(String sessionUUID, String imageCode) {
        if(StringUtils.hasText(sessionUUID)&&StringUtils.hasText(imageCode)){
            String auth = redisTemplate.opsForValue().get(AUTH_CODE_PREFIX + sessionUUID);
            if(!imageCode.equalsIgnoreCase(auth)){
                throw new AuthenticationException("验证码错误");
            }
        }else {
            throw new RuntimeException("验证码或UUID为空");
        }
    }

    @ApiOperation("获取验证码图片")
    @GetMapping("captcha.jpg")
    public void captcha(@RequestParam(required = true) String uuid,
                                          HttpServletResponse response){
        log.info("获取验证码，uuid为{}",uuid);
        //使用hutool使用验证码
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(150, 45, 4, 10);

        String code = lineCaptcha.getCode();
        //将验证码放入redis里面,并设置过期时间
        redisTemplate.opsForValue().set(AUTH_CODE_PREFIX+uuid,code,60, TimeUnit.SECONDS);
        log.info("验证码为{}",code);
        try {
            response.getOutputStream().write(lineCaptcha.getImageBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @ApiOperation("获取到当前的用户")
    @GetMapping("/sys/user/info")
    @Log(name = "获取到当前的用户")
    public ResponseEntity<Map<String, Object>> getUser(){
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("userId",user.getUserId());
        hashMap.put("userName", user.getUsername());
        return ResponseEntity.ok(hashMap);
    }
    @GetMapping("/sys/user/page555")
    //@RequiresPermissions("sys:user:page")
    public String adminAdd(){

        return "adminadd";
    }

    @GetMapping("/root/add")
   // @RequiresPermissions("root:add")
    public String rootAdd(){

        return "rootAdd";
    }
}
